﻿using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Elmah;

namespace ScoutNET.Attributes
{
    public class HandleErrorWithELMAHAttribute : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            base.OnException(filterContext);

            string errorMessage = filterContext.Exception.Message;

            string[] saBreadcrumb = new String[2];
            saBreadcrumb[0] = HtmlHelper.GenerateLink(filterContext.RequestContext, RouteTable.Routes, Resources.Master_Breadcrumb_Home, "Default", "Index", "Home", null, null);
            saBreadcrumb[1] = Resources.Error_Error500_Breadcrumb;

            ViewDataDictionary viewData = new ViewDataDictionary();
            viewData.Add("Breadcrumb", saBreadcrumb);
            viewData.Add("PageTitle", Resources.Error_Error500_Title);
            viewData.Add("ErrorMessage", errorMessage);

            var e = filterContext.Exception;
            if (!filterContext.ExceptionHandled || RaiseErrorSignal(e) || IsFiltered(filterContext))
            {
                filterContext.Result = new ViewResult { ViewName = "Error500", ViewData = viewData };
            }
            else
            {
                filterContext.Result = new ViewResult { ViewName = "Error500", ViewData = viewData };
                LogException(e);
            }
        }

        private static bool RaiseErrorSignal(Exception e)
        {
            var context = HttpContext.Current;
            if (context == null)
            {
                return false;
            }

            var signal = ErrorSignal.FromContext(context);
            if (signal == null)
            {
                return false;
            }
            signal.Raise(e, context);
            
            return true;
        }

        private static bool IsFiltered(ExceptionContext context)
        {
            var config = context.HttpContext.GetSection("elmah/errorFilter") as ErrorFilterConfiguration;

            if (config == null)
            {
                return false;
            }

            var testContext = new ErrorFilterModule.AssertionHelperContext(context.Exception, HttpContext.Current);

            return config.Assertion.Test(testContext);
        }

        private static void LogException(Exception e)
        {
            var context = HttpContext.Current;
            ErrorLog.GetDefault(context).Log(new Error(e, context));
        }
    }
}
